#include "libBigNum.h"

/*
Author - Ido
Bignumber compare operators
*/
bool isFractionalPartZero(int  _arr_size, int _fractionalPart, unsigned long *_num_array)
{
	
	if ( _fractionalPart > 0)
	{
		int i;
		for( i = ( _arr_size - _fractionalPart); i < _arr_size; i++)
			if( _num_array[i] != 0)
				return false;
	}
	
	return true;
}

bool big_number::operator==(const big_number& other) const
{
	int i;

	if( _sign != other._sign)
		return false;

	if( ( _arr_size - _fractionalPart) != ( other._arr_size - other._fractionalPart))
		return false;
	
	for( i=0; i < ( _arr_size - _fractionalPart); i++)
	{
		if( _num_array[i] != other._num_array[i])
			return false;
	}
	
	if ( isFractionalPartZero(_arr_size, _fractionalPart, _num_array) &&
		 isFractionalPartZero(other._arr_size, other._fractionalPart, other._num_array))
		 return true;

	if(  _fractionalPart != other._fractionalPart)
		return false;
	
	for( i = ( _arr_size - _fractionalPart); i < _arr_size; i++)
	{
		if( _num_array[i] != other._num_array[i])
			return false;
	}

	return true;
}

bool big_number::operator!=(const big_number& other) const
{
	return !(*this == other);
}

bool big_number::operator< (const big_number& other) const
{
	int i, rez = -1;
	bool flag = true;

	// this == other 
	if( *this == other)
		return false;

	//this>0 and num<0
	if( _sign && !other._sign) 
		return false;

	//this<0 and num>0
	if(  !_sign && other._sign) 
		return true;

	 // if integral array size of this > other 
	if( ( _arr_size - _fractionalPart) > ( other._arr_size - other._fractionalPart))
	{
		rez = 0;
	}
	else
	{
		// if integral array size of this < other
		if( ( _arr_size - _fractionalPart) < ( other._arr_size - other._fractionalPart)) 
		{
			rez = 1;
		}
		else
		{
			// integral array size is equel 
			for( i=0; i < ( _arr_size - _fractionalPart); i++)
			{ 
				if( _num_array[i] > other._num_array[i])
				{
					rez = 0;
					break;
				}

				if( _num_array[i] < other._num_array[i])
				{
					rez = 1;
					break;
				}
			}
		}

	}
	
	if( rez == -1)
	{
		if( _fractionalPart < other._fractionalPart)
		{
			for( i = ( _arr_size - _fractionalPart); i < _arr_size; i++)
			{
				if( _num_array[i] > other._num_array[i])
				{
					rez = 0;
					break;
				}
					
				if( _num_array[i] < other._num_array[i])
				{
					rez = 1;
					break;
				}
			}

			if ( rez == -1)
				rez = 1;
		}
		else
		{	
			for( i = ( other._arr_size - other._fractionalPart); i < other._arr_size; i++)
			{
				if( _num_array[i] > other._num_array[i])
				{
					rez = 0;
					break;
				}
				if( _num_array[i] < other._num_array[i])
				{
					rez = 1;
					break;
				}
			}
			if ( rez == -1)
				rez = 0;
		}
	}

	if( !_sign && !other._sign) // this<0 and num<0
		rez = rez==1?0:1;

	return rez==1?true:false;
}

bool big_number::operator> (const big_number& other) const
{
	return other < *this;
}

bool big_number::operator<= (const big_number& other) const
{
	return !(*this > other);
}

bool big_number::operator>= (const big_number& other) const
{
	return !(*this < other);
}

bool operator== (char &l, big_number &r){return big_number(l)==r;}
bool operator!= (char &l, big_number &r){return big_number(l)!=r;}
bool operator< (char &l, big_number &r){return big_number(l)<r;}
bool operator> (char &l, big_number &r){return big_number(l)>r;}
bool operator<= (char &l, big_number &r){return big_number(l)<=r;}
bool operator>= (char &l, big_number &r){return big_number(l)>=r;}

bool operator== (short &l, big_number &r){return big_number(l)==r;}
bool operator!= (short &l, big_number &r){return big_number(l)!=r;}
bool operator< (short &l, big_number &r){return big_number(l)<r;}
bool operator> (short &l, big_number &r){return big_number(l)>r;}
bool operator<= (short &l, big_number &r){return big_number(l)<=r;}
bool operator>= (short &l, big_number &r){return big_number(l)>=r;}

bool operator== (int &l, big_number &r){return big_number(l)==r;}
bool operator!= (int &l, big_number &r){return big_number(l)!=r;}
bool operator< (int &l, big_number &r){return big_number(l)<r;}
bool operator> (int &l, big_number &r){return big_number(l)>r;}
bool operator<= (int &l, big_number &r){return big_number(l)<=r;}
bool operator>= (int &l, big_number &r){return big_number(l)>=r;}

bool operator== (long &l, big_number &r){return big_number(l)==r;}
bool operator!= (long &l, big_number &r){return big_number(l)!=r;}
bool operator< (long &l, big_number &r){return big_number(l)<r;}
bool operator> (long &l, big_number &r){return big_number(l)>r;}
bool operator<= (long &l, big_number &r){return big_number(l)<=r;}
bool operator>= (long &l, big_number &r){return big_number(l)>=r;}

bool operator== (long long &l, big_number &r){return big_number(l)==r;}
bool operator!= (long long &l, big_number &r){return big_number(l)!=r;}
bool operator< (long long &l, big_number &r){return big_number(l)<r;}
bool operator> (long long &l, big_number &r){return big_number(l)>r;}
bool operator<= (long long &l, big_number &r){return big_number(l)<=r;}
bool operator>= (long long &l, big_number &r){return big_number(l)>=r;}

bool operator== (unsigned char &l, big_number &r){return big_number(l)==r;}
bool operator!= (unsigned char &l, big_number &r){return big_number(l)!=r;}
bool operator< (unsigned char &l, big_number &r){return big_number(l)<r;}
bool operator> (unsigned char &l, big_number &r){return big_number(l)>r;}
bool operator<= (unsigned char &l, big_number &r){return big_number(l)<=r;}
bool operator>= (unsigned char &l, big_number &r){return big_number(l)>=r;}

bool operator== (unsigned short &l, big_number &r){return big_number(l)==r;}
bool operator!= (unsigned short &l, big_number &r){return big_number(l)!=r;}
bool operator< (unsigned short &l, big_number &r){return big_number(l)<r;}
bool operator> (unsigned short &l, big_number &r){return big_number(l)>r;}
bool operator<= (unsigned short &l, big_number &r){return big_number(l)<=r;}
bool operator>= (unsigned short &l, big_number &r){return big_number(l)>=r;}

bool operator== (unsigned int &l, big_number &r){return big_number(l)==r;}
bool operator!= (unsigned int &l, big_number &r){return big_number(l)!=r;}
bool operator< (unsigned int &l, big_number &r){return big_number(l)<r;}
bool operator> (unsigned int &l, big_number &r){return big_number(l)>r;}
bool operator<= (unsigned int &l, big_number &r){return big_number(l)<=r;}
bool operator>= (unsigned int &l, big_number &r){return big_number(l)>=r;}

bool operator== (unsigned long &l, big_number &r){return big_number(l)==r;}
bool operator!= (unsigned long &l, big_number &r){return big_number(l)!=r;}
bool operator< (unsigned long &l, big_number &r){return big_number(l)<r;}
bool operator> (unsigned long &l, big_number &r){return big_number(l)>r;}
bool operator<= (unsigned long &l, big_number &r){return big_number(l)<=r;}
bool operator>= (unsigned long &l, big_number &r){return big_number(l)>=r;}

bool operator== (unsigned long long &l, big_number &r){return big_number(l)==r;}
bool operator!= (unsigned long long &l, big_number &r){return big_number(l)!=r;}
bool operator< (unsigned long long &l, big_number &r){return big_number(l)<r;}
bool operator> (unsigned long long &l, big_number &r){return big_number(l)>r;}
bool operator<= (unsigned long long &l, big_number &r){return big_number(l)<=r;}
bool operator>= (unsigned long long &l, big_number &r){return big_number(l)>=r;}

bool operator== (float &l, big_number &r){return big_number(l)==r;}
bool operator!= (float &l, big_number &r){return big_number(l)!=r;}
bool operator< (float &l, big_number &r){return big_number(l)<r;}
bool operator> (float &l, big_number &r){return big_number(l)>r;}
bool operator<= (float &l, big_number &r){return big_number(l)<=r;}
bool operator>= (float &l, big_number &r){return big_number(l)>=r;}

bool operator== (double &l, big_number &r){return big_number(l)==r;}
bool operator!= (double &l, big_number &r){return big_number(l)!=r;}
bool operator< (double &l, big_number &r){return big_number(l)<r;}
bool operator> (double &l, big_number &r){return big_number(l)>r;}
bool operator<= (double &l, big_number &r){return big_number(l)<=r;}
bool operator>= (double &l, big_number &r){return big_number(l)>=r;}

bool operator== (long double &l, big_number &r){return big_number(l)==r;}
bool operator!= (long double &l, big_number &r){return big_number(l)!=r;}
bool operator< (long double &l, big_number &r){return big_number(l)<r;}
bool operator> (long double &l, big_number &r){return big_number(l)>r;}
bool operator<= (long double &l, big_number &r){return big_number(l)<=r;}
bool operator>= (long double &l, big_number &r){return big_number(l)>=r;}